package com.inke.box.net.minasocket;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.ToastUtils;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Administrator on 2017/11/8.
 */

public class InkeMinaClientService extends Service{

    private boolean isConn = false;
    private static InkeMinaClientService inkeMinaClient;
    private NioSocketConnector nioSocketConnector;
    private MinaClientConnCallBack minaClientConnCallBack;
    private int threadNumber=10;
    private ThreadPoolExecutor threadPool;
    private int corePoolSize = 100;
    private int maxPoolSize = 200;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public static InkeMinaClientService getInstance(){
        return inkeMinaClient;
    }


    /**
     * 设置连接状态回调
     * */
    public InkeMinaClientService setMinaClientConnCallBack(MinaClientConnCallBack minaClientConnCallBack) {
        this.minaClientConnCallBack = minaClientConnCallBack;
        return inkeMinaClient;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        inkeMinaClient = this;

    }

    public void creaMinaSocketConnector(){
        nioSocketConnector = new NioSocketConnector();
        //接手数据过滤器
        DefaultIoFilterChainBuilder filterChain = nioSocketConnector.getFilterChain();
        TextLineCodecFactory factory = new TextLineCodecFactory(Charset.forName("UTF-8"), LineDelimiter.WINDOWS.getValue(), LineDelimiter.WINDOWS.getValue());
//        factory.setDecoderMaxLineLength(10 * 1024 * 1024);//(系统默认MyTextLineCodecFactory传输限制为1k，这里设置可以扩大传输，主要用于较大图片传输)
//        factory.setEncoderMaxLineLength(10 * 1024 * 1024);
        // 设定这个过滤器将以对象为单位读取数据
        ProtocolCodecFilter filter = new ProtocolCodecFilter(factory);
        // 设定服务器端的消息处理器:一个SamplMinaServerHandler对象,
        filterChain.addLast("codec",filter);
        filterChain.addLast("logger", new LoggingFilter());
        nioSocketConnector.setHandler(new InkeClientSocketHanlder(minaClientConnCallBack));
        // Set connect timeout
//        nioSocketConnector.setConnectTimeoutCheckInterval(30);
    }

    /**
     * 轮询探测服务器地址
     * */
    public void connLoopServerIp(){

        if (NetworkUtils.isWifiConnected()){
            isConn = false;

            threadPool = new ThreadPoolExecutor(corePoolSize, maxPoolSize, 60, TimeUnit.SECONDS,
                        new LinkedBlockingQueue<Runnable>());

            //获取连接wifi的地址  192.168.1.1
            String ipAddress = NetworkUtils.getIPAddress(true);
            int i = ipAddress.lastIndexOf(".");
            //截取当前wifi路由地址 192.168.1
            String ip = ipAddress.substring(0, i+1);

            //ip末尾端 1  255
            for (int x=1;x<255;x++){
                //服务器端口区间 10010    10020
                for(int port=10010;port<10020;port++){
                    if (isConn){
                        threadPool.shutdown();
                    }
                    String server_ip = ip+x;
                    threadPool.execute(new PingServerIpPortRunnable(server_ip,x,port));
                }
            }

            //扫描完毕 关闭线程池
            threadPool.shutdown();

        }else {
            ToastUtils.showShort("请先连接WIFI");
        }

    }

    /**
     * 多线程扫描服务器Ip
     * */
    class PingServerIpPortRunnable implements Runnable{


        private String server_ip;
        private int x;//ip段位
        private int mPort;
        public PingServerIpPortRunnable(String server_ip,int x,int mPort){
            this.server_ip = server_ip;
            this.x = x;
            this.mPort = mPort;
        }

        @Override
        public void run() {
                    if (isConn){
                        return;
                    }
                    LogUtils.e("ip:"+server_ip+"__prot:"+mPort);
                    Socket socket = new Socket();
                    InetSocketAddress inetSocketAddress = new InetSocketAddress(server_ip, mPort);

                    try {
                        //ping连接服务器ip和端口
                        socket.connect(inetSocketAddress,3000);
                        if (socket.isConnected()){
                            LogUtils.e("连接服务器成功____ip:"+server_ip+"__prot:"+mPort);
                            isConn=true;
                            clientStart(server_ip,mPort);
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        try {
                            socket.close();
                            LogUtils.e("close__"+x+"__"+mPort);
                            //扫描完毕 仍然连接不到服务器
                            if (x==254&&mPort==10019){
                                if (minaClientConnCallBack!=null)
                                    minaClientConnCallBack.onConnectError("自动连接服务器失败,请保证在连接同一个wifi");
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

            }
    }





    /**
     * 连接服务器
     * */
    public void clientStart(final String ip, final int port){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    creaMinaSocketConnector();
                    //连接服务器
                    ConnectFuture connect = nioSocketConnector.connect(new InetSocketAddress(ip,port));
                    if (!connect.isConnected()){
                        return;
                    }
                    IoSession session = connect.getSession();
                    if (session!=null){
                        if (session.isConnected()){
                            LogUtils.e("ClientSocket System go go go");
                            session.getCloseFuture().awaitUninterruptibly();
                        }
                        nioSocketConnector.dispose(true);
                    }

                }catch (Exception e){
                    e.printStackTrace();
                    LogUtils.e("ClientSocket 启动失败:");

                }
            }
        }).start();

    }


}
